home *** CD-ROM | disk | FTP | other *** search
- /* File drawmap.c */
-
- #include <functions.h>
- #include <devices/printer.h>
- #include <errno.h>
- #include <exec/io.h>
- #include <exec/libraries.h>
- #include <exec/memory.h>
- #include <fcntl.h>
- #include <graphics/gfxmacros.h>
- #include <intuition/intuition.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
-
- #include "reqbase.h"
- #include "ILBM_lib.h"
- #include "drawmap-menu.h"
- #include "drawmap.h"
- #include "drawmap-req.h"
- #include "drawmap-help.h"
- #include "drawmap-proto.h"
-
- struct Screen *s; /* pointer to screen */
- struct Window *w; /* pointer to Window */
- struct RastPort *rp; /* pointer to RastPort */
- struct ViewPort *vp; /* pointer to ViewPort */
- struct TmpRas mapTmpRas; /* temp raster for flood fill */
- struct Library *GfxBase;
- struct Library *IntuitionBase;
- struct Remember *rememberkey; /* pointer for cleaning up */
-
- struct ReqLib *ReqBase; /* address of requester library */
- struct ExtendedColorRequester colorstruct;
- struct ReqFileRequester filereq;
- char filename[FCHARS]; /* space for save file and */
- char directoryname[DSIZE]; /* dir name */
- char pathname[DSIZE+FCHARS]; /* full path and file name */
-
- struct ILBMBase *ILBMBase; /* address of ILBM library */
- ILBMFrame IlbmFrame;
-
- unsigned short *arrow, *cross; /* storage for mouse pointers */
- unsigned short *waiter, *transparent;
-
- unsigned char *bp[DEPTH]; /* bitplane pointers */
-
- struct Requester req;
-
- struct BitMap map_bitmap; /* holding area for initial flat map */
- struct RastPort map_rp; /* rastport for initial flat map */
- char got_flat_map;
-
- static long title_toggle = FALSE;
-
- /* ============================================================= */
-
- main (void)
-
- {
- struct IntuiMessage *msg;
- PLANEPTR workspace;
- int ix;
- FILE *config;
-
- rememberkey = NULL; /* initialize rememberkey */
- if ((GfxBase = (struct Library *) OpenLibrary ("graphics.library", 0L))
- == NULL) {
- printf ("Can't open graphics library\n");
- exit (10);
- }
- if ((IntuitionBase=(struct Library *) OpenLibrary ("intuition.library",0L))
- == NULL) {
- printf ("Can't open intuition library\n");
- goto end1;
- }
- if ((ReqBase = (struct ReqLib *) OpenLibrary ("req.library", 0L))
- == NULL) {
- printf ("Can't open req.library\n");
- goto end2;
- }
- if ((ILBMBase = (struct ILBMBase *) OpenLibrary ("ilbm.library", 0L))
- == NULL) {
- printf ("Can't open ilbm.library\n");
- goto end3;
- }
- if ((s = (struct Screen *) OpenScreen (&mapscreen)) == NULL) {
- printf ("Can't open screen\n");
- goto end4;
- }
- mapWindow.Screen = s;
- newhelpw.Screen = s;
- if ((w = (struct Window *) OpenWindow (&mapWindow)) == NULL) {
- printf ("Can't open window\n");
- goto end5;
- }
- /* load default color table */
- CopyMem ((char *) mapcolors, (char *) configcolors,
- sizeof(mapcolors));
- if ((config = fopen (configfile, "rb")) != NULL) {
- if ((ix = fread ((char *) &configcolors[0], sizeof (char),
- sizeof(configcolors), config))
- != sizeof(configcolors)) {
- CopyMem ((char *) mapcolors, (char *) configcolors,
- sizeof(mapcolors));
- }
- fclose (config);
- }
- vp = &(s->ViewPort); /* pointer to viewport */
- LoadRGB4 (vp, &configcolors[0], NUM_COLORS); /* init. color values */
- /* init. mouse pointers */
- arrow = (UWORD *) AllocRemember (&rememberkey, ARROW_SIZE, MEMF_CHIP);
- CopyMem ((char *) arrow_data, (char *) arrow, ARROW_SIZE);
-
- cross = (UWORD *) AllocRemember (&rememberkey, CROSS_SIZE, MEMF_CHIP);
- CopyMem ((char *) cross_data, (char *) cross, CROSS_SIZE);
-
- waiter = (UWORD *) AllocRemember (&rememberkey, WAITER_SIZE, MEMF_CHIP);
- CopyMem ((char *) waiter_data, (char *) waiter, WAITER_SIZE);
-
- transparent = (UWORD *) AllocRemember (&rememberkey, TRANSPARENT_SIZE,
- MEMF_CHIP);
- CopyMem ((char *) transparent_data, (char *) transparent,
- TRANSPARENT_SIZE);
-
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16, WAITER_X_OFFSET,
- WAITER_Y_OFFSET);
-
- rp = w->RPort;
- if ((workspace = (PLANEPTR) AllocRaster (WWIDTH,WHEIGHT)) == NULL) {
- printf ("No space for Temporary Raster\n");
- goto end6;
- }
-
- InitBitMap (&map_bitmap, DEPTH, WWIDTH, WHEIGHT);
- InitRastPort (&map_rp);
- map_rp.BitMap = &map_bitmap;
-
- for (ix=0; ix<DEPTH; ++ix) /* initialize flat map storage area */
- map_bitmap.Planes[ix] = NULL;
- for (ix=0; ix<DEPTH; ++ix) {
- map_bitmap.Planes[ix] = (PLANEPTR) AllocRaster (WWIDTH, WHEIGHT);
- if (map_bitmap.Planes[ix] == NULL) {
- printf ("No space for bitmap workspace\n");
- goto end7;
- }
- } /* temp raster for flood fill */
- InitTmpRas (&mapTmpRas, workspace, RASSIZE(WWIDTH,WHEIGHT));
- rp->TmpRas = &mapTmpRas; /* link it to the RastPort */
-
- if ((ix = readmap ()) != OK) { /* read map files */
- printf ("Error reading map files\n");
- goto end7;
- }
- if ((ix = get_min_max ()) != OK) {
- printf ("Map files are corrupted\n");
- goto end7;
- }
-
- if ((ix = init_helpitems ()) != OK)
- printf ("\nUnable to initialize help information, but continuing\n");
-
- loadmappic(); /* load initial flat map */
-
- for (ix=0; ix<DEPTH; ++ix) /* initialize bitplane pointers */
- bp[ix] = rp->BitMap->Planes[ix];
-
- init_requesters (); /* initialize the requesters */
-
- SetMenuStrip (w, &menu[0]); /* bring up the menus */
-
- SetAPen (rp, ORANGE); /* set initial drawing pens */
- SetBPen (rp, BLUE);
- SetDrMd (rp, JAM2);
-
- view_height = VIEW_HEIGHT; /* constants for globe view */
- eta = view_height/RE;
- facp = 1. + eta;
- etap = 1./facp;
-
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16, ARROW_X_OFFSET, ARROW_Y_OFFSET);
-
- while (1) { /* wait for message from */
- WaitPort ( w->UserPort ); /* Intuition */
- if ((msg = (struct IntuiMessage *) GetMsg (w->UserPort)) == NULL)
- continue;
- else if ((ix = handle_event (msg)) != OK)
- break;
- else
- ReplyMsg (msg);
- }
- ReplyMsg (msg);
- if (helpbuffer != NULL)
- free (helpbuffer);
- PurgeFiles (&filereq); /* clean up after file requester */
- end7:
- for (ix=0; ix<DEPTH; ++ix)
- if (map_bitmap.Planes[ix] != NULL)
- FreeRaster (map_bitmap.Planes[ix], WWIDTH, WHEIGHT);
- FreeRaster (workspace, WWIDTH, WHEIGHT);
- end6:
- FreeRemember (&rememberkey, TRUE); /* clean up */
- ClearPointer (w);
- ClearMenuStrip (w);
- Forbid (); /* strip remaining messages */
- while (1) {
- if ((msg = (struct IntuiMessage *) GetMsg (w->UserPort)) == NULL)
- break;
- else
- ReplyMsg (msg);
- }
- ModifyIDCMP (w, NULL);
- Permit ();
- CloseWindow (w);
- end5:
- CloseScreen (s);
- end4:
- CloseLibrary (ILBMBase);
- end3:
- CloseLibrary (ReqBase);
- end2:
- CloseLibrary (IntuitionBase);
- end1:
- CloseLibrary (GfxBase);
- }
-
- /* ============================================================= */
-
- int handle_event (struct IntuiMessage *msg)
- /* processes main Intuition events */
- {
- static char box_error[] = "Box of zero size not allowed";
- static char *dlevels[] = { "High", "Medium high",
- "Medium", "Medium low",
- "Low" };
- static char drag_prompt[] = "Press and drag left button to "
- "select box, right button to "
- "abort";
- static char expandbox_error[] = "Invalid map displayed for Box "
- "Zoom Out option";
- static char flood_wait[] = "Press left button to select area "
- "to fill, right button to abort";
- static char fmt_DETAIL_LEVEL_TYPE[] = "%s detail level";
- static char fmt_ORBITAL_TYPE[] = "Orbital...view from %.2lf "
- "kilometers";
- static char fmt_ZOOM_IN_TYPE[] = "Zoom In...view from %.2lf "
- "kilometers";
- static char fmt_ZOOM_OUT_TYPE[] = "Zoom Out...view from %.2lf "
- "kilometers";
- static char grid_error[] = "Invalid map displayed for Grid "
- "option";
- static char lines_wait[] = "Press left button to draw lines, "
- "right button to abort";
- static char press_prompt[] = "Press left button to select "
- "center point, right button to "
- "abort";
- static char print_abort[] = "Printing aborted";
- static char print_error[] = "Printer error";
- static char print_wait[] = "Printing...press right button to "
- "abort";
- static char smallbox_error[] = "Invalid map displayed for Box "
- "Zoom In option";
- static char title_BOX_TYPE[] = "Box";
- static char title_BOX_ZOOM_IN_TYPE[] = "Box Zoom In";
- static char title_BOX_ZOOM_OUT_TYPE[] = "Box Zoom Out";
- static char title_CLEARS_TYPE[] = "Clear Screen";
- static char title_COAST_COLOR_TYPE[] = "Color for Coastlines";
- static char title_COUNTRY_COLOR_TYPE[] = "Color for Countries";
- static char title_DRAW_LINE_TYPE[] = "Draw Lines";
- static char title_FLAT_TYPE[] = "Flat Map";
- static char title_FLOOD_COLOR_TYPE[] = "Color for Flood Fill";
- static char title_FLOOD_TYPE[] = "Flood Fill";
- static char title_GLOBE_TYPE[] = "Globe...view from infinitely far "
- "away";
- static char title_HELP_TYPE[] = "Display help file";
- static char title_HELP_TYPE_error[] = "Error displaying help information";
- static char title_ISLAND_COLOR_TYPE[] = "Color for Islands";
- static char title_LAKE_COLOR_TYPE[] = "Color for Lakes";
- static char title_LINE_COLOR_TYPE[] = "Color for lines";
- static char title_MERCATOR_TYPE[] = "Mercator";
- static char title_PALETTE_TYPE[] = "Modify Color Palette";
- static char title_PRINT_TYPE[] = "Print Screen";
- static char title_REDRAW_TYPE[] = "Redraw";
- static char title_REDRAW_TYPE_error[] = "Invalid map displayed for Redraw "
- "option";
- static char title_RESET_COLOR_TYPE[] = "Reset Colors";
- static char title_RIVER_COLOR_TYPE[] = "Color for Rivers";
- static char title_SHADOW_TYPE[] = "Shadow";
- static char title_STATE_COLOR_TYPE[] = "Color for States";
- static char title_TEXT_COLOR_TYPE[] = "Color for text";
- static char title_TEXT_TYPE[] = "Text";
- static char title_abort[] = "Selection aborted";
- static char title_buffer[] = " "
- " ";
- static char title_config_not_saved[] = "Configuration not saved";
- static char title_config_saved[] = "Configuration saved to disk";
- static char title_not_saved[] = "Screen not saved";
- static char title_saved[] = "Screen saved to disk";
- static char first_time = TRUE;
- static long oldtype = -1L;
- static long flood_color = DK_GRN;
- static long line_color = LT_YEL;
- static long text_color = WHITE;
- static double lamg, latg;
- static double lat[2], lam[2];
- struct IntuiMessage *msgf;
- FILE *config;
- char abort;
- unsigned short select;
- long x, y, x0, y0;
- int i, result;
- long menunum, itemnum, subnum, type;
- double latb[2], lamb[2], del, av;
-
- disable_menus (IDCMPFLAGS); /* disable menus while do this event */
- abort = FALSE;
- if (first_time == TRUE) {
- first_time = FALSE;
- if (got_flat_map == OK)
- oldtype = FLAT_TYPE;
- }
- switch (msg->Class) {
- case MENUPICK:
- select = msg->Code;
- if (select == MENUNULL) /* no extended selections */
- break;
- menunum = MENUNUM (select);
- itemnum = ITEMNUM (select);
- subnum = SUBNUM (select);
- type = (long) (100*menunum+itemnum)*100+subnum; /* menu selection */
- switch (menunum) {
- case PROJECT:
- switch (itemnum) {
- case HELP:
- SetWindowTitles (w, 0, title_HELP_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- if ((result = displayhelp ()) != OK) {
- SetWindowTitles (w, 0, title_HELP_TYPE_error);
- DisplayBeep (0);
- }
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- break;
- case SAVEIT:
- ModifyIDCMP (w, CLOSEWINDOW);
- if ((result = save_to_disk ()) != OK) {
- SetWindowTitles (w, 0, title_not_saved);
- DisplayBeep (0);
- }
- else
- SetWindowTitles (w, 0, title_saved);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- ModifyIDCMP (w, IDCMPFLAGS);
- break;
- case SAVE_CONFIG:
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- if ((config = fopen (configfile, "wb")) != NULL) {
- if ((i = fwrite ((char *) &configcolors[0], sizeof (char),
- sizeof(configcolors), config))
- == sizeof(configcolors))
- SetWindowTitles (w, 0, title_config_saved);
- else {
- SetWindowTitles (w, 0, title_config_not_saved);
- DisplayBeep (0);
- }
- fclose (config);
- }
- else {
- SetWindowTitles (w, 0, title_config_not_saved);
- DisplayBeep (0);
- }
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- break;
- case PRINT:
- SetWindowTitles (w, 0, print_wait);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- if ((result = printmap (w)) == OK)
- SetWindowTitles (w, 0, title_PRINT_TYPE);
- else {
- if (result == NOT_OK)
- SetWindowTitles (w, 0, print_error);
- else
- SetWindowTitles (w, 0, print_abort);
- DisplayBeep (0);
- }
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- break;
- case CLEARS:
- SetWindowTitles (w, 0, title_CLEARS_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- SetRast (rp, BLUE);
- oldtype = type;
- break;
- case QUIT:
- enable_menus ();
- return (NOT_OK);
- break;
- default:
- break;
- }
- break;
- case BOUNDARIES:
- switch (itemnum) {
- case COASTLINES:
- map[COASTLINES].plot ^= 1;
- break;
- case COUNTRIES:
- map[COUNTRIES].plot ^= 1;
- break;
- case STATES:
- map[STATES].plot ^= 1;
- break;
- case ISLANDS:
- map[ISLANDS].plot ^= 1;
- break;
- case LAKES:
- map[LAKES].plot ^= 1;
- break;
- case RIVERS:
- map[RIVERS].plot ^= 1;
- break;
- case DETAIL_LEVEL:
- detail_level = subnum + 1;
- sprintf (title_buffer, fmt_DETAIL_LEVEL_TYPE,
- dlevels[subnum]);
- SetWindowTitles (w, 0, title_buffer);
- break;
- default:
- break;
- }
- break;
- case MAPS:
- switch (itemnum) {
- case PLANE:
- switch (subnum) {
- case FLAT:
- SetWindowTitles (w, 0, title_FLAT_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- fullmap (FLAT_TYPE);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- oldtype = type;
- break;
- case MERCATOR:
- SetWindowTitles (w, 0, title_MERCATOR_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- fullmap (MERCATOR_TYPE);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- oldtype = type;
- break;
- default:
- break;
- }
- break;
- case SPHERE:
- switch (subnum) {
- case ZOOM_IN: /* zoom views */
- case ZOOM_OUT:
- if (type==ZOOM_IN_TYPE) {
- view_height /= 2.;
- if (view_height<MIN_HEIGHT)
- view_height = MIN_HEIGHT;
- sprintf (title_buffer, fmt_ZOOM_IN_TYPE, view_height);
- }
- else {
- view_height *= 2.;
- sprintf (title_buffer, fmt_ZOOM_OUT_TYPE, view_height);
- }
- eta = view_height/RE;
- facp = 1. + eta;
- etap = 1./facp;
- case GLOBE: /* globe views */
- case ORBITAL:
- if ( (type!=ZOOM_IN_TYPE && type!=ZOOM_OUT_TYPE) ||
- (oldtype!=ZOOM_IN_TYPE && oldtype!=ZOOM_OUT_TYPE &&
- oldtype!=GLOBE_TYPE && oldtype!=ORBITAL_TYPE) ) {
- SetWindowTitles (w, 0, press_prompt);
- /* wait for mouse button */
- if (oldtype!=FLAT_TYPE && oldtype!=MERCATOR_TYPE) {
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- showmappic ();
- ModifyIDCMP (w, IDCMPFLAGS);
- oldtype = FLAT_TYPE;
- }
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- SetPointer (w, cross, CROSS_SIZE/4-2, 16,
- CROSS_X_OFFSET, CROSS_Y_OFFSET);
- while (1) {
- WaitPort (w->UserPort);
- if ((msgf = (struct IntuiMessage *) GetMsg (w->UserPort))
- ==NULL)
- continue;
- else if (msgf->Code==SELECTDOWN)
- break;
- else if (msgf->Code == MENUDOWN) {
- abort = TRUE;
- ReplyMsg (msgf);
- SetWindowTitles (w, 0, title_abort);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- DisplayBeep (0);
- break;
- }
- else
- ReplyMsg (msgf);
- }
- if (abort == TRUE)
- break;
- x = msgf->MouseX; /* get mouse position */
- y = msgf->MouseY;
- ReplyMsg (msgf);
- getcoord (x, y, oldtype, &latg, &lamg);
- }
- if (type==ORBITAL_TYPE) {
- get_user_input (ORBITAL_TYPE, x, y, &view_height,
- &x0, &y0);
- eta = view_height/RE; /* initialize values for */
- facp = 1. + eta; /* orbital view */
- etap = 1./facp;
- sprintf (title_buffer, fmt_ORBITAL_TYPE, view_height);
- SetWindowTitles (w, 0, title_buffer);
- }
- else if (type==GLOBE_TYPE)
- SetWindowTitles (w, 0, title_GLOBE_TYPE);
- else
- SetWindowTitles (w, 0, title_buffer);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- globe (latg, lamg, type); /* draw map */
- stars ();
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- oldtype = type;
- break;
- default:
- break;
- }
- break;
- case BOXES:
- switch (subnum) {
- case BOX_ZOOM_IN: /* box zoom in */
- if (oldtype != BOX_TYPE && oldtype != BOX_ZOOM_IN_TYPE &&
- oldtype != BOX_ZOOM_OUT_TYPE) {
- SetWindowTitles (w, 0, smallbox_error);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- DisplayBeep (0);
- break;
- } /* and fall through to */
- case BOX: /* ordinary box request */
- SetWindowTitles (w, 0, drag_prompt);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- if (type == BOX_TYPE && (oldtype!=FLAT_TYPE &&
- oldtype!=MERCATOR_TYPE)) {
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- showmappic ();
- ModifyIDCMP (w, IDCMPFLAGS);
- oldtype = FLAT_TYPE;
- }
- SetPointer (w, cross, CROSS_SIZE/4-2, 16,
- CROSS_X_OFFSET, CROSS_Y_OFFSET);
- if ((result = getbox (&x0, &y0, &x, &y)) != OK) {
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- if (result == ABORT)
- SetWindowTitles (w, 0, title_abort);
- else
- SetWindowTitles (w, 0, box_error);
- DisplayBeep (0);
- break;
- }
- if (type == BOX_TYPE)
- SetWindowTitles (w, 0, title_BOX_TYPE);
- else
- SetWindowTitles (w, 0, title_BOX_ZOOM_IN_TYPE);
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- if (type == BOX_TYPE) {
- getcoord (x0, y0, oldtype, &lat[0], &lam[0]);
- getcoord (x, y, oldtype, &lat[1], &lam[1]);
- }
- else {
- getcoord_box (x0, y0, lat, lam, &latb[0], &lamb[0]);
- getcoord_box (x, y, lat, lam, &latb[1], &lamb[1]);
- lat[0] = latb[0];
- lat[1] = latb[1];
- lam[0] = lamb[0];
- lam[1] = lamb[1];
- }
- box (lat, lam);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- oldtype = type;
- break;
- case BOX_ZOOM_OUT: /* box zoom out */
- if (oldtype != BOX_TYPE && oldtype != BOX_ZOOM_IN_TYPE &&
- oldtype != BOX_ZOOM_OUT_TYPE) {
- SetWindowTitles (w, 0, expandbox_error);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- DisplayBeep (0);
- break;
- }
- SetWindowTitles (w, 0, title_BOX_ZOOM_OUT_TYPE);
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- del = EXPAND_SCALE_FACTOR * (lat[0] - lat[1])/2.;
- av = (lat[0] + lat[1])/2.;
- lat[0] = av + del;
- lat[1] = av - del;
- if (lat[0] > 90.)
- lat[0] = 90.;
- if (lat[1] < -90.)
- lat[1] = -90.;
- del = EXPAND_SCALE_FACTOR * (lam[1] - lam[0])/2.;
- av = (lam[0] + lam[1])/2.;
- lam[0] = av - del;
- lam[1] = av + del;
- if (lam[0] < -180.)
- lam[0] = -180.;
- if (lam[1] > 180.)
- lam[1] = 180.;
- box (lat, lam);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- oldtype = type;
- break;
- default:
- break;
- }
- break;
- case REDRAW: /* redraw previous map */
- if (oldtype != FLAT_TYPE && oldtype != MERCATOR_TYPE &&
- oldtype != GLOBE_TYPE && oldtype != ORBITAL_TYPE &&
- oldtype != ZOOM_IN_TYPE && oldtype != ZOOM_OUT_TYPE &&
- oldtype != BOX_TYPE && oldtype != BOX_ZOOM_IN_TYPE &&
- oldtype != BOX_ZOOM_OUT_TYPE) {
- SetWindowTitles (w, 0, title_REDRAW_TYPE_error);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- DisplayBeep (0);
- break;
- }
- SetWindowTitles (w, 0, title_REDRAW_TYPE);
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- if (oldtype == FLAT_TYPE || oldtype == MERCATOR_TYPE)
- fullmap (oldtype);
- else if (oldtype == ZOOM_IN_TYPE || oldtype == ZOOM_OUT_TYPE ||
- oldtype == GLOBE_TYPE || oldtype == ORBITAL_TYPE) {
- globe (latg, lamg, oldtype);
- stars ();
- }
- else
- box (lat, lam);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- break;
- default:
- break;
- }
- break;
- case COLORS:
- switch (itemnum) {
- case PALETTE:
- SetWindowTitles (w, 0, title_PALETTE_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- result = ExtendedColorRequester (&colorstruct);
- for (i=0; i<NUM_COLORS; ++i)
- configcolors[i] = GetRGB4 (vp->ColorMap, i);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- break;
- case RESET_COLOR:
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- LoadRGB4 (vp, &mapcolors[0], NUM_COLORS);
- CopyMem ((char *) mapcolors, (char *) configcolors,
- sizeof(mapcolors));
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- SetWindowTitles (w, 0, title_RESET_COLOR_TYPE);
- break;
- case FLOOD_COLOR:
- flood_color = subnum;
- SetWindowTitles (w, 0, title_FLOOD_COLOR_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- break;
- case LINE_COLOR:
- line_color = subnum;
- SetWindowTitles (w, 0, title_LINE_COLOR_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- break;
- case TEXT_COLOR:
- text_color = subnum;
- SetWindowTitles (w, 0, title_TEXT_COLOR_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- break;
- case COAST_COLOR:
- map[COASTLINES].color = subnum;
- SetWindowTitles (w, 0, title_COAST_COLOR_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- break;
- case COUNTRY_COLOR:
- map[COUNTRIES].color = subnum;
- SetWindowTitles (w, 0, title_COUNTRY_COLOR_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- break;
- case STATE_COLOR:
- map[STATES].color = subnum;
- SetWindowTitles (w, 0, title_STATE_COLOR_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- break;
- case ISLAND_COLOR:
- map[ISLANDS].color = subnum;
- SetWindowTitles (w, 0, title_ISLAND_COLOR_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- break;
- case LAKE_COLOR:
- map[LAKES].color = subnum;
- SetWindowTitles (w, 0, title_LAKE_COLOR_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- break;
- case RIVER_COLOR:
- map[RIVERS].color = subnum;
- SetWindowTitles (w, 0, title_RIVER_COLOR_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- break;
- default:
- break;
- }
- break;
- case EDIT:
- switch (itemnum) {
- case GRID:
- if (oldtype!=FLAT_TYPE && oldtype!=MERCATOR_TYPE &&
- oldtype!=GLOBE_TYPE && oldtype!=ORBITAL_TYPE &&
- oldtype!=ZOOM_IN_TYPE && oldtype!=ZOOM_OUT_TYPE) {
- SetWindowTitles (w, 0, grid_error);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- DisplayBeep (0);
- }
- else {
- ModifyIDCMP (w, CLOSEWINDOW);
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- grid (oldtype, latg, lamg);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ModifyIDCMP (w, IDCMPFLAGS);
- }
- break;
- case FLOOD:
- SetWindowTitles (w, 0, flood_wait);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- SetPointer (w, cross, CROSS_SIZE/4-2, 16,
- CROSS_X_OFFSET, CROSS_Y_OFFSET);
- if ((result = floodfill (flood_color)) == OK)
- SetWindowTitles (w, 0, title_FLOOD_TYPE);
- else {
- SetWindowTitles (w, 0, title_abort);
- DisplayBeep (0);
- }
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- break;
- case DRAW_LINE:
- SetWindowTitles (w, 0, lines_wait);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- SetPointer (w, cross, CROSS_SIZE/4-2, 16,
- CROSS_X_OFFSET, CROSS_Y_OFFSET);
- if ((result = draw_line (line_color)) == OK)
- SetWindowTitles (w, 0, title_DRAW_LINE_TYPE);
- else {
- SetWindowTitles (w, 0, title_abort);
- DisplayBeep (0);
- }
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- break;
- case SHADOW:
- ModifyIDCMP (w, CLOSEWINDOW);
- ShowTitle (s, FALSE); /* don't shadow the title */
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- shadow ();
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- SetWindowTitles (w, 0, title_SHADOW_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- ModifyIDCMP (w, IDCMPFLAGS);
- break;
- case TEXT:
- x = msg->MouseX;
- y = msg->MouseY;
- if ((result = do_text (x, y, text_color)) == ABORT) {
- SetWindowTitles (w, 0, title_abort);
- DisplayBeep (0);
- }
- else
- SetWindowTitles (w, 0, title_TEXT_TYPE);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- break;
- case TTOGGLE:
- title_toggle ^= 1L;
- ShowTitle (s, title_toggle);
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- enable_menus (); /* re-enable menu events */
- return (OK);
- }
-
- /* ================================================================ */
-
- void box (double *latp, double *lamp) /* draws areas contained within */
- /* a rectangular region */
- {
- char first, prev_in_view, in_view;
- short h1, h1c, h1prev; /* x-dist. (pix) from center */
- short h2, h2c, h2prev; /* y-dist. (pix) from center */
- long x, y;
- int i, na, nc;
- int lat1i, lat2i, lam1i, lam2i;
- double lam, lamc, lamprev; /* longitude */
- double lat, latc, latprev; /* latitude */
- double bwidth, bheight, bcx, bcy, xscale, yscale;
- double lat1, lat2, lam1, lam2;
- struct Arc *seg;
- struct Pt *pt;
-
- lat1 = latp[0]; /* store values for box corners */
- lat2 = latp[1]; /* locally */
- lam1 = lamp[0];
- lam2 = lamp[1];
- lat1i = 60.*lat1; /* convert to signed minutes */
- lat2i = 60.*lat2;
- lam1i = 60.*lam1;
- lam2i = 60.*lam2;
- bwidth = lam2 - lam1; /* box width (degrees) */
- bheight = lat1 - lat2; /* box height (degrees) */
- bcx = (lam1 + lam2)/2.; /* x-coord of box center (deg) */
- bcy = (lat1 + lat2)/2.; /* y-coord of box center (deg) */
- xscale = WWIDTH / bwidth; /* horizontal scale (pix/deg) */
- yscale = WHEIGHT / bheight; /* vertical scale (pix/deg) */
- first = TRUE;
- SetRast (rp, BLUE); /* blue background */
- SetAPen (rp, ORANGE); /* outline the box */
- drawbox (0, 0, WWIDTH-1, WHEIGHT-1);
- for (nc=0; nc<NUM_MAPS; ++nc) { /* do each map type */
- if (map[nc].plot != TRUE) /* if not requested, skip */
- continue;
- SetAPen (rp, map[nc].color); /* initialize color */
- seg = map[nc].seg;
- pt = map[nc].pt; /* do each segment */
- for (na=0; na<map[nc].nsegs; ++na) {
- first = TRUE; /* skip if not in view */
- if (seg[na].lat_min > lat1i || seg[na].lat_max < lat2i ||
- seg[na].lam_min > lam2i || seg[na].lam_max < lam1i)
- continue;
- for (i=seg[na].first; i<=seg[na].last; ++i) {
- if (pt[i].code < detail_level) /* filter by detail level */
- continue;
- lat = pt[i].lat; /* latitude */
- lat /= 60.;
- lam = pt[i].lam; /* longitude */
- lam /= 60.;
- in_view = FALSE; /* get status of current point */
- if ( (lat<=lat1 && lat>=lat2)
- && (lam>=lam1 && lam<=lam2)) {
- in_view = TRUE;
- h1 = (lam-bcx) * xscale;
- h2 = - (lat-bcy) * yscale;
- }
- if (first==TRUE) { /* check first point */
- first = FALSE;
- if (in_view==TRUE) { /* if first point is in view, */
- x = h1 + CENTERX; /* move pen to first point */
- y = h2 + CENTERY; /* and plot it */
- WritePixel (rp, x, y);
- Move (rp, x, y);
- h1prev = h1;
- h2prev = h2;
- }
- prev_in_view = in_view; /* save status of first point */
- latprev = lat;
- lamprev = lam;
- continue;
- }
- if (in_view==TRUE) {
- if (prev_in_view==FALSE) { /* prev. point was not in view */
- box_rim_point (lat, lam, latprev, lamprev, lat1, lam1,
- lat2, lam2, &latc, &lamc);
- h1c = (lamc-bcx) * xscale;
- h2c = - (latc-bcy) * yscale;
- x = h1c + CENTERX; /* move to rim point & plot it */
- y = h2c + CENTERY;
- WritePixel (rp, x, y);
- Move (rp, x, y);
- h1prev = h1c;
- h2prev = h2c;
- }
- if (h1!=h1prev || h2!=h2prev) {
- x = h1 + CENTERX; /* draw to current point */
- y = h2 + CENTERY;
- if (ABS(h1-h1prev) > WWIDTH/2)
- WritePixel (rp, x, y);
- else
- Draw (rp, x, y);
- Move (rp, x, y);
- }
- h1prev = h1;
- h2prev = h2;
- }
- else { /* else out of view */
- if (prev_in_view==TRUE) { /* previous point was in view */
- box_rim_point (lat, lam, latprev, lamprev, lat1, lam1,
- lat2, lam2, &latc, &lamc);
- h1c = (lamc-bcx) * xscale;
- h2c = - (latc-bcy) * yscale;
- x = h1c + CENTERX; /* draw to rim point */
- y = h2c + CENTERY;
- if (ABS(h1c-h1prev) > WWIDTH/2)
- WritePixel (rp, x, y);
- else
- Draw (rp, x, y);
- Move (rp, x, y);
- }
- }
- prev_in_view = in_view; /* save status of current point */
- latprev = lat;
- lamprev = lam;
- }
- }
- }
- }
-
- /* ================================================================ */
-
- /* find rim points in box view */
-
- void box_rim_point (double lat, double lam, double latprev,
- double lamprev, double lat1, double lam1,
- double lat2, double lam2, double *latc,
- double *lamc)
- {
- double dlam, dlat, tlam1, tlam2, tlat1, tlat2;
-
- dlam = lam - lamprev; /* use parametric linear */
- dlat = lat - latprev; /* interpolation */
- if (dlam == 0.) { /* same longitude */
- tlam1 = tlam2 = -1.;
- tlat1 = (lat1 - latprev) / dlat;
- tlat2 = (lat2 - latprev) / dlat;
- }
- else if (dlat == 0.) { /* same latitude */
- tlam1 = (lam1 - lamprev) / dlam;
- tlam2 = (lam2 - lamprev) / dlam;
- tlat1 = tlat2 = -1.;
- }
- else {
- tlam1 = (lam1 - lamprev) / dlam;
- tlam2 = (lam2 - lamprev) / dlam;
- tlat1 = (lat1 - latprev) / dlat;
- tlat2 = (lat2 - latprev) / dlat;
- }
- if (tlam1 >= 0. && tlam1 <= 1.) { /* now find rim point */
- (*lamc) = lam1;
- (*latc) = latprev + tlam1 * dlat;
- }
- else if (tlam2 >= 0. && tlam2 <= 1.) {
- (*lamc) = lam2;
- (*latc) = latprev + tlam2 * dlat;
- }
- else if (tlat1 >= 0. && tlat1 <= 1.) {
- (*lamc) = lamprev + tlat1 * dlam;
- (*latc) = lat1;
- }
- else {
- (*lamc) = lamprev + tlat2 * dlam;
- (*latc) = lat2;
- }
- }
-
- /* ============================================================= */
-
- void disable_menus (long flags) /* disables menus */
-
- {
- ModifyIDCMP (w, flags);
- Forbid ();
- w->Flags |= RMBTRAP;
- Permit ();
- }
-
- /* ============================================================= */
-
- int displayhelp (void) /* displays help information */
-
- {
- struct IntuiMessage *msg;
- int gadgetnum;
-
- if (helpbuffer == NULL)
- return (NOT_OK);
- if ((hw = (struct Window *) OpenWindow (&newhelpw)) == NULL)
- return (NOT_OK);
- SetPointer (hw, arrow, ARROW_SIZE/4-2, 16, ARROW_X_OFFSET,
- ARROW_Y_OFFSET);
- DrawBorder (hw->RPort, &border1, 0, 0);
- while (1) {
- WaitPort (hw->UserPort);
- if ((msg = (struct IntuiMessage * ) GetMsg (hw->UserPort)) == NULL)
- continue;
- gadgetnum = ((struct Gadget *) (msg->IAddress))->GadgetID;
- ReplyMsg (msg);
- if (gadgetnum < NUMGADGETS-1) {
- SetPointer (hw, waiter, WAITER_SIZE/4-2, 16, WAITER_X_OFFSET,
- WAITER_Y_OFFSET);
- ModifyIDCMP (hw, NULL);
- dohelpitem (gadgetnum);
- ModifyIDCMP (hw, GADGETUP);
- SetPointer (hw, arrow, ARROW_SIZE/4-2, 16, ARROW_X_OFFSET,
- ARROW_Y_OFFSET);
- }
- if (gadgetnum == NUMGADGETS-1)
- break;
- }
- ClearPointer (hw);
- CloseWindow (hw);
- return (OK);
- }
-
- /* ============================================================= */
-
- void dohelpitem (int num)
-
- {
- static char defaulttext[] = "No help information to display";
- char *txt;
- short result;
- int disp;
-
- if ((disp = gadgetlist[num].disp) < 0)
- txt = defaulttext;
- else
- txt = &(helpbuffer[disp]);
- trs.Text = txt;
- trs.Window = hw;
- trs.Title = gadgetlist[num].text;
- result = TextRequest (&trs);
- }
-
- /* ============================================================= */
-
- int do_text (long xin, long yin, long color) /* get user text input */
-
- {
- struct IntuiMessage *msg1;
- static char title_setdown[] = "Press left button to position text,"
- " right button to cancel";
- long x, y, xold, yold;
- int pixlength;
- double t;
- /* get user text */
- get_user_input (TEXT_TYPE, xin, yin, &t, &xold, &yold);
- pixlength = TextLength (rp, user_text_input, strlen(user_text_input));
- SetWindowTitles (w, 0, title_setdown);
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- SetDrMd (rp, JAM2 | COMPLEMENT); /* turn on complement mode */
- SetPointer (w, transparent, TRANSPARENT_SIZE/4-2, 16,
- TRANSPARENT_X_OFFSET, TRANSPARENT_Y_OFFSET);
- drawbox (xold, yold, xold+pixlength-1, yold-9);
- ModifyIDCMP (w, IDCMPFLAGS | MOUSEMOVE);
- while (1) {
- WaitPort (w->UserPort); /* wait for mouse button */
- if ((msg1 = (struct IntuiMessage *) GetMsg (w->UserPort)) == NULL)
- continue;
- else {
- x = msg1->MouseX; /* get current mouse position */
- y = msg1->MouseY; /* and erase old box */
- if (msg1->Code == SELECTDOWN) {
- ReplyMsg (msg1); /* done if select button pressed */
- drawbox (xold, yold, xold+pixlength-1, yold-9);
- break;
- }
- else if (msg1->Class == MOUSEMOVE) {
- /* else draw box at current position */
- drawbox (xold, yold, xold+pixlength-1, yold-9);
- drawbox (x, y, x+pixlength-1, y-9);
- xold = x;
- yold = y;
- }
- else if (msg1->Code == MENUDOWN) {
- ReplyMsg (msg1);
- ModifyIDCMP (w, IDCMPFLAGS);
- drawbox (xold, yold, xold+pixlength-1, yold-9);
- SetDrMd (rp, JAM2);
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- return (ABORT);
- }
- ReplyMsg (msg1);
- }
- }
- Move (rp, x, y-2); /* move to current mouse position */
- SetDrMd (rp, JAM1); /* (-2 to allow for font baseline) */
- SetAPen (rp, color); /* draw text */
- Text (rp, user_text_input, strlen(user_text_input));
- SetDrMd (rp, JAM2);
- ModifyIDCMP (w, IDCMPFLAGS); /* enable original event types */
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- return (OK);
- }
-
- /* ============================================================= */
-
- void drawbox (long x1, long y1, long x2, long y2) /* draws a box */
-
- {
- box_border.LeftEdge = x1;
- box_border.TopEdge = y1;
- box_borderpts[2] = box_borderpts[4] = x2-x1;
- box_borderpts[5] = box_borderpts[7] = y2-y1;
- DrawBorder (rp, (struct Border *) &box_border, 0, 0);
- }
-
- /* ============================================================= */
-
- int draw_line (long color) /* draws a line based on */
- /* mouse positions */
- {
- struct IntuiMessage *msg;
- char selectbutton;
- long x, y;
-
- selectbutton = FALSE;
- SetAPen (rp, color);
- SetDrMd (rp, JAM2);
- ModifyIDCMP (w, IDCMPFLAGS | MOUSEMOVE); /* enable mouse move events */
- while (1) {
- WaitPort (w->UserPort);
- if ((msg = (struct IntuiMessage *) GetMsg (w->UserPort)) == NULL)
- continue;
- else if (msg->Code == MENUDOWN) { /* stop if press menu button */
- ReplyMsg (msg);
- ModifyIDCMP (w, IDCMPFLAGS); /* disable mouse move events */
- return (ABORT);
- }
- else if (msg->Code == SELECTDOWN) {
- x = msg->MouseX; /* get current mouse position */
- y = msg->MouseY;
- WritePixel (rp, x, y);
- Move (rp, x, y);
- selectbutton = TRUE;
- }
- else if (selectbutton == TRUE && msg->Class == MOUSEMOVE) {
- x = msg->MouseX; /* get current mouse position */
- y = msg->MouseY;
- Draw (rp, x, y); /* draw to current position */
- Move (rp, x, y);
- }
- else if (selectbutton == TRUE && msg->Code == SELECTUP)
- break;
- ReplyMsg (msg);
- }
- ReplyMsg (msg);
- ModifyIDCMP (w, IDCMPFLAGS); /* enable original event types */
- return (OK);
- }
-
- /* ============================================================= */
-
- void enable_menus (void) /* enables menus */
-
- {
- ModifyIDCMP (w, IDCMPFLAGS);
- Forbid ();
- w->Flags &= ~RMBTRAP;
- Permit ();
- }
-
- /* ============================================================= */
-
- int floodfill (long flood_color) /* flood fills an area based */
- /* on mouse position */
- {
- struct IntuiMessage *msgf;
- long x, y;
-
- while (1) {
- WaitPort (w->UserPort); /* wait for message */
- if ((msgf = (struct IntuiMessage *) GetMsg (w->UserPort)) == NULL)
- continue;
- else if (msgf->Code==SELECTDOWN)
- break;
- else if (msgf->Code == MENUDOWN) {
- ReplyMsg (msgf);
- return (ABORT);
- }
- else
- ReplyMsg (msgf);
- }
- x = msgf->MouseX; /* get mouse coordinates */
- y = msgf->MouseY;
- ReplyMsg (msgf);
- SetAPen (rp, flood_color);
- Flood (rp, 1, x, y); /* flood fill the region */
- return (OK);
- }
-
- /* ============================================================= */
-
- void fullmap (long type) /* draws flat and mercator */
- /* map projections */
- {
- short h1, h2, h1old, h2old;
- long x, y;
- int i, na, nc, np;
- double t;
- struct Arc *seg;
- struct Pt *pt;
-
- SetRast (rp, BLUE); /* clear screen */
- for (nc=0; nc<NUM_MAPS; ++nc) { /* do each map type */
- if (map[nc].plot != TRUE) /* if not requested, skip */
- continue;
- SetAPen (rp, map[nc].color); /* initialize color */
- seg = map[nc].seg;
- pt = map[nc].pt; /* do each segment */
- for (na=0; na<map[nc].nsegs; ++na) {
- np = 0;
- for (i=seg[na].first; i<=seg[na].last; ++i) {
- if (pt[i].code < detail_level) /* filter by detail level */
- continue;
- t = pt[i].lat; /* y = latitude */
- if (type==FLAT_TYPE)
- t *= (VFACTOR/60.);
- else if (type==MERCATOR_TYPE) {
- t = (t/120. + 45.) * RAD;
- t = log (tan (t)) * M_VFACTOR;
- }
- if (t<0.) /* round to nearest pixel */
- t -= 0.5;
- else
- t += 0.5;
- h2 = -t;
- t = pt[i].lam; /* x = longitude */
- t *= (HFACTOR/60.);
- if (t<0.) /* round to nearest pixel */
- t -= 0.5;
- else
- t += 0.5;
- h1 = t;
- x = h1 + CENTERX;
- y = h2 + CENTERY;
- if (np!=0) { /* disallow identical adjacent pts */
- if (h1==h1old && h2==h2old)
- continue;
- else if (ABS (h1-h1old) > WWIDTH/2)
- WritePixel (rp, x, y);
- else
- Draw (rp, x, y);
- }
- else
- WritePixel (rp, x, y);
- Move (rp, x, y);
- h1old = h1;
- h2old = h2;
- ++np;
- }
- }
- }
- if (got_flat_map != OK && type == FLAT_TYPE) {
- savemappic (); /* save map in save area */
- got_flat_map = OK;
- }
- }
-
- /* ============================================================= */
-
- int getbox (long *x0, long *y0, long *x, long *y)
- /* selects a region to draw to */
- /* larger scale */
- {
- struct IntuiMessage *msgf;
- char selectbutton;
- long xd, yd, x1, x2, y1, y2;
-
- selectbutton = FALSE;
- SetDrMd (rp, JAM2 | COMPLEMENT); /* turn on complement mode and */
- ModifyIDCMP (w, IDCMPFLAGS | MOUSEMOVE); /* enable mouse move events */
- while (1) {
- WaitPort (w->UserPort);
- if ((msgf = (struct IntuiMessage *) GetMsg (w->UserPort)) == NULL)
- continue;
- else if (msgf->Code == MENUDOWN) { /* abort if user pressed */
- ReplyMsg (msgf); /* menu button */
- ModifyIDCMP (w, IDCMPFLAGS);
- SetDrMd (rp, JAM2);
- return (ABORT);
- }
- else if (msgf->Code==SELECTDOWN) { /* if user pressed left button, */
- xd = x1 = msgf->MouseX; /* get initial mouse position */
- yd = y1 = msgf->MouseY;
- drawbox (x1, y1, xd, yd); /* draw initial box */
- selectbutton = TRUE;
- }
- else if (selectbutton==TRUE && msgf->Class==MOUSEMOVE) {
- x2 = msgf->MouseX;
- y2 = msgf->MouseY;
- drawbox (x1, y1, xd, yd); /* erase old box */
- xd = x2;
- yd = y2;
- drawbox (x1, y1, xd, yd); /* draw new box */
- }
- else if (selectbutton==TRUE && msgf->Code==SELECTUP)
- break;
- ReplyMsg (msgf);
- }
- ModifyIDCMP (w, IDCMPFLAGS); /* disable mouse events and */
- x2 = msgf->MouseX; /* erase current box */
- y2 = msgf->MouseY;
- ReplyMsg (msgf);
- drawbox (x1, y1, xd, yd);
- SetDrMd (rp, JAM2); /* restore original drawing mode */
- *x0 = x1;
- *y0 = y1;
- *x = x2;
- *y = y2;
- if (x1==x2 || y1==y2) /* error if box is of zero area */
- return (NOT_OK);
- if (x1>x2 && y1>y2) { /* ensure that the vertices of */
- *x0 = x2; /* the box are in the proper */
- *y0 = y2; /* order */
- *x = x1;
- *y = y1;
- }
- else if (x1<x2 && y1>y2) {
- *x0 = x1;
- *y0 = y2;
- *x = x2;
- *y = y1;
- }
- else if (x1>x2 && y1<y2) {
- *x0 = x2;
- *y0 = y1;
- *x = x1;
- *y = y2;
- }
- return (OK);
- }
-
- /* ============================================================= */
-
- void getcoord (long x, long y, long type, double *lat, double *lam)
- /* converts screen coordinates */
- /* into latitude and longitude */
- /* for flat and Mercator maps */
- {
- (*lam) = (x - CENTERX) / HFACTOR;
- if (type==FLAT_TYPE)
- (*lat) = (CENTERY - y) / VFACTOR;
- else
- (*lat) = -90. + 2.*atan(exp((CENTERY-y)/M_VFACTOR))/RAD;
- }
-
- /* ============================================================= */
-
- /* get latitude and longitude */
- /* for Box Zoom In option */
- void getcoord_box (long x, long y, double latin[2], double lamin[2],
- double *latout, double *lamout)
- {
- (*lamout) = (((double) (x)) / WWIDTH) * (lamin[1]-lamin[0]) + lamin[0];
- (*latout) = (((double) (y)) / WHEIGHT) * (latin[1]-latin[0]) + latin[0];
- }
-
- /* ============================================================= */
-
- int get_min_max (void) /* find limits of each segment */
-
- {
- FILE *fin;
- struct Arc *seg, *tseg;
- struct Pt *pt;
- int na, i, j, ix, first_seg;
-
- if ((seg = (struct Arc *) AllocRemember (&rememberkey,
- NSEGS*sizeof(struct Arc),
- MEMF_PUBLIC | MEMF_CLEAR)) == NULL) {
- printf ("Unable to get space for limits array\n");
- return (NOT_OK);
- }
- for (i=0; i<NUM_MAPS; ++i) { /* link segment array to maps */
- first_seg = map[i].first_seg;
- map[i].seg = (struct Arc *) &(seg[first_seg].lat_min);
- }
- if ((fin = fopen (limitsfile, "rb")) != NULL) {
- ix = fread (seg, sizeof(struct Arc), NSEGS, fin);
- fclose (fin);
- if (ix == NSEGS)
- return (OK);
- else
- printf ("Limits file corrupted, building it afresh\n");
- }
- for (i=0; i<NUM_MAPS; ++i) { /* build limits array in units */
- pt = map[i].pt; /* address of map points */
- tseg = map[i].seg; /* address of segments for map */
- for (j=0, na=-1; j<map[i].numpts; ++j) {
- if (pt[j].code > MAX_DETAIL_LEVEL) {
- ++na;
- if (na >= map[i].nsegs)
- break;
- tseg[na].first = tseg[na].last = j;
- tseg[na].lat_min = tseg[na].lat_max = pt[j].lat;
- tseg[na].lam_min = tseg[na].lam_max = pt[j].lam;
- continue;
- }
- if (pt[j].lat < tseg[na].lat_min)
- tseg[na].lat_min = pt[j].lat;
- if (pt[j].lat > tseg[na].lat_max)
- tseg[na].lat_max = pt[j].lat;
- if (pt[j].lam < tseg[na].lam_min)
- tseg[na].lam_min = pt[j].lam;
- if (pt[j].lam > tseg[na].lam_max)
- tseg[na].lam_max = pt[j].lam;
- tseg[na].last = j;
- }
- }
- ix = 0; /* save limits to disk */
- if ((fin = fopen (limitsfile, "wb")) != NULL) {
- ix = fwrite (seg, sizeof(struct Arc), NSEGS, fin);
- fclose (fin);
- }
- if (ix != NSEGS) /* error in saving to disk */
- printf ("Unable to save limits to disk, continuing anyway\n");
- return (OK);
- }
-
- /* ============================================================= */
-
- void get_user_input (long type, long xin, long yin, double *d,
- long *xout, long *yout)
- /* prompts for user input */
- /* (text or doubleword) */
- {
- struct IntuiMessage *msg;
- struct Gadget *g;
- long x, y;
- /* position the requester */
- x = xin - GAD_LEFT - 8*(NUM_CHAR-2);
- y = yin - GAD_TOP - 2;
- if ((x+TWIDTH) >= WWIDTH)
- x = WWIDTH - TWIDTH - 15;
- if (x < 10)
- x = 10;
- if ((y+THEIGHT) >= WHEIGHT)
- y = WHEIGHT - THEIGHT - 15;
- if (y < 5)
- y = 5;
- req.LeftEdge = x;
- req.TopEdge = y;
- if (type == ORBITAL_TYPE) { /* initialize for doubleword input */
- req.ReqText = &dtext;
- gadgetinput.Buffer = &user_double_input[0];
- }
- else { /* initialize for text input */
- req.ReqText = &rtext;
- gadgetinput.Buffer = &user_text_input[0];
- }
- Request (&req, w); /* issue the requester */
- ModifyIDCMP (w, GADGETUP); /* disable other events */
- ActivateGadget (&gad, w, &req);
- while (1) {
- WaitPort (w->UserPort);
- if ((msg = (struct IntuiMessage *) GetMsg (w->UserPort)) == NULL)
- continue;
- else if (msg->Class == GADGETUP) {
- g = (struct Gadget *) (msg->IAddress);
- if (g->GadgetID != GAD_FIRST) {
- ReplyMsg (msg);
- continue;
- }
- *xout = msg->MouseX; /* get mouse coordinates */
- *yout = msg->MouseY;
- ReplyMsg (msg);
- if (type == ORBITAL_TYPE) { /* get user value */
- *d = atof (&user_double_input[0]);
- if (errno == ERANGE) { /* trap erroneous input */
- *d = VIEW_HEIGHT; /* store default value */
- sprintf (user_double_input, "%.2lf", *d);
- DisplayBeep (0);
- }
- else if ((*d) < MIN_HEIGHT) {
- *d = MIN_HEIGHT; /* store minimum value */
- sprintf (user_double_input, "%.2lf", *d);
- DisplayBeep (0);
- }
- }
- break;
- }
- else /* ignore inappropriate events */
- ReplyMsg (msg);
- }
- ModifyIDCMP (w, IDCMPFLAGS);
- }
-
- /* ============================================================= */
-
- void globe (double lat0, double lam0, long type)
- /* draws globe projections */
- {
- char first, prev_in_view, in_view, latzero;
- short h1, h1c, h1prev; /* x-dist. (pix) from center */
- short h2, h2c, h2prev; /* y-dist. (pix) from center */
- long x, y;
- int i, na, nc;
- double lam, lamc, lamprev; /* longitude */
- double lat, latc, latprev; /* latitude */
- double c0, s0, c1, s1, c2, zp, zpprev;
- double hp, fac2, fac3, scale;
- double h1d, h2d, lat0p;
- double latmin, latmax, lammin, lammax;
- struct Arc *seg;
- struct Pt *pt;
-
- latzero = FALSE;
- if (type==GLOBE_TYPE) { /* ordinary globe view */
- hp = 0.;
- scale = 1.;
- fac3 = 1.;
- }
- else { /* orbital globe view */
- hp = etap;
- scale = sqrt (1.-etap*etap);
- fac3 = (facp/(facp-hp)) * scale;
- }
- if (lat0==0.) {
- c0 = 1.;
- s0 = 0.;
- if (type==GLOBE_TYPE)
- latzero = TRUE; /* equatorial, ordinary globe view */
- }
- else {
- lat0p = lat0 * RAD;
- c0 = cos (lat0p);
- s0 = sin (lat0p);
- }
- SetRast (rp, BLACK); /* black background */
- SetAPen (rp, BLUE); /* blue globe */
- DrawEllipse (rp, (long) CENTERX, (long) CENTERY, (long) HRADIUS,
- (long) VRADIUS);
- Flood (rp, 1, CENTERX, CENTERY);
- for (nc=0; nc<NUM_MAPS; ++nc) { /* do each map type */
- if (map[nc].plot != TRUE) /* if not requested, skip */
- continue;
- SetAPen (rp, map[nc].color);
- seg = map[nc].seg;
- pt = map[nc].pt; /* do each segment */
- for (na=0; na<map[nc].nsegs; ++na) {
- latmin = ((double) (seg[na].lat_min)) / 60.;
- latmax = ((double) (seg[na].lat_max)) / 60.;
- lammin = ((double) (seg[na].lam_min)) / 60.;
- lammax = ((double) (seg[na].lam_max)) / 60.;
- if ((i = globe_in_view (latmax, lammin, latmin, lammax, lat0, lam0,
- hp)) != OK)
- continue;
- first = TRUE;
- for (i=seg[na].first; i<=seg[na].last; ++i) {
- if (pt[i].code < detail_level) /* filter by detail level */
- continue;
- lat = pt[i].lat; /* latitude */
- lat *= (RAD/60.);
- lam = pt[i].lam; /* longitude */
- lam = (lam/60. - lam0) * RAD;
- if (lam<-PI)
- lam += TWOPI;
- if (lam>PI)
- lam -= TWOPI;
- c1 = cos(lat); /* cosine of latitude */
- s1 = sin(lat); /* sine of latitude */
- in_view = FALSE; /* get status of current point */
- if (latzero==TRUE) { /* equatorial globe view */
- zp = c1*cos (lam);
- if (lam>=-PI2 && lam<=+PI2) {
- in_view = TRUE;
- h1 = HRADIUS * c1 * sin (lam);
- h2 = -VRADIUS * s1;
- }
- }
- else { /* oblique earth view */
- c2 = cos (lam);
- zp = s1*s0 + c1*c0*c2;
- if (zp>=hp) { /* zp > hp => in view */
- in_view = TRUE;
- h1d = HRADIUS * c1 * sin (lam);
- h2d = -VRADIUS * (s1*c0 -c1*s0*c2);
- if (type!=GLOBE_TYPE) {
- fac2 = (facp/(facp-zp)) * scale;
- h1d *= fac2;
- h2d *= fac2;
- }
- h1 = h1d;
- h2 = h2d;
- }
- }
- if (first==TRUE) { /* get status of first point */
- first = FALSE;
- if (in_view==TRUE) { /* if first point is in view, */
- x = h1 + CENTERX; /* move pen to first point */
- y = h2 + CENTERY; /* and plot it */
- Move (rp, x, y);
- WritePixel (rp, x, y);
- h1prev = h1;
- h2prev = h2;
- }
- prev_in_view = in_view; /* save status of first point */
- latprev = lat;
- lamprev = lam;
- zpprev = zp;
- continue;
- }
- if (in_view==TRUE) { /* current point is in view, */
- if (prev_in_view==FALSE) { /* previous point was not */
- globe_rim_point (lat, lam, latprev, lamprev, zp, zpprev,
- c0, s0, fac3, type, latzero,
- &latc, &lamc, &h1c, &h2c);
- x = h1c + CENTERX; /* move to rim point & plot it */
- y = h2c + CENTERY;
- Move (rp, x, y);
- WritePixel (rp, x, y);
- h1prev = h1c;
- h2prev = h2c;
- }
- if (h1!=h1prev || h2!=h2prev) {
- x = h1 + CENTERX; /* draw to current point */
- y = h2 + CENTERY;
- Draw (rp, x, y);
- Move (rp, x, y);
- }
- h1prev = h1;
- h2prev = h2;
- }
- else { /* current point out of view, */
- if (prev_in_view==TRUE) { /* previous point in view */
- globe_rim_point (lat, lam, latprev, lamprev, zp, zpprev,
- c0, s0, fac3, type, latzero,
- &latc, &lamc, &h1c, &h2c);
- x = h1c + CENTERX; /* draw to rim point */
- y = h2c + CENTERY;
- Draw (rp, x, y);
- Move (rp, x, y);
- }
- }
- prev_in_view = in_view; /* save status of current point */
- latprev = lat;
- lamprev = lam;
- zpprev = zp;
- }
- }
- }
- }
-
- /* ============================================================= */
-
- void globe_grid (long type, double lat0, double lam0)
- /* controls drawing globe grid */
- {
- static double lat_interval = 20.;
- static double lam_interval = 30.;
- static double delta = 5.;
- char first;
- int k;
- double lat, lam, c0, s0, c1, s1, c2, s2, rlam, rlat;
- double hp, scale, fac3, dlat, dlam, ddelt;
- double lamp[2], latp[2];
-
- lat0 *= RAD;
- c0 = cos (lat0);
- s0 = sin (lat0);
- dlat = lat_interval;
- dlam = lam_interval;
- ddelt = delta;
- if (type==GLOBE_TYPE) { /* ordinary globe view */
- hp = 0.;
- scale = 1.;
- fac3 = 1.;
- }
- else { /* orbital view */
- hp = etap;
- scale = sqrt (1.-etap*etap);
- fac3 = (facp/(facp-hp)) * scale;
- if (view_height<=1200.) {
- dlat /= 4.;
- dlam /= 4.;
- ddelt /= 5.;
- }
- }
- SetAPen (rp, BLACK); /* grid lines in black */
- for (lat=80.; lat>=-80.; lat-=dlat) { /* lines of equal latitude */
- rlat = lat*RAD;
- if ((k=limit_lam (&lamp[0], rlat, lat0, hp))!=OK)
- continue; /* skip if entirely out of view */
- lamp[0] += lam0;
- lamp[1] += lam0;
- k = lamp[0]/ddelt - 1.; /* express limits as multiple */
- lamp[0] = k*ddelt; /* of ddelt */
- k = lamp[1]/ddelt + 1.;
- lamp[1] = k*ddelt;
- c1 = cos (rlat);
- s1 = sin (rlat);
- first = TRUE;
- if (lat==0.)
- SetAPen (rp, WHITE); /* draw equator in white */
- for (lam=lamp[0]; lam<=lamp[1]; lam+=ddelt) {
- rlam = (lam-lam0)*RAD;
- if (rlam<-PI)
- rlam += TWOPI;
- if (rlam>+PI)
- rlam -= TWOPI;
- c2 = cos (rlam);
- s2 = sin (rlam);
- globe_grid_plot (rlat, rlam, c0, s0, c1, s1, c2, s2,
- type, hp, scale, fac3, &first);
- }
- if (lat==0.)
- SetAPen (rp, BLACK); /* reset pen to black */
- }
- for (lam=-180.; lam<+180.; lam+=dlam) { /* meridian circles */
- rlam = (lam-lam0)*RAD;
- if (rlam<-PI)
- rlam += TWOPI;
- if (rlam>+PI)
- rlam -= TWOPI;
- if ((k=limit_lat (&latp[0], lat0, rlam, hp))!=OK)
- continue; /* skip if entirely out of view */
- k = latp[0]/ddelt + 1.; /* express limits as multiple */
- latp[0] = k*ddelt; /* of ddelt */
- k = latp[1]/ddelt - 1.;
- latp[1] = k*ddelt;
- if (latp[0]>=90.) /* exclude North polar point */
- latp[0] = 90. - ddelt;
- if (latp[1]<=-90.) /* exclude South polar point */
- latp[1] = -90. + ddelt;
- c2 = cos (rlam);
- s2 = sin (rlam);
- first = TRUE;
- if (lam==0. || lam==-180.) /* prime meridian in white */
- SetAPen (rp, WHITE);
- for (lat=latp[0]; lat>=latp[1]; lat-=ddelt) {
- rlat = lat*RAD;
- c1 = cos (rlat);
- s1 = sin (rlat);
- globe_grid_plot (rlat, rlam, c0, s0, c1, s1, c2, s2,
- type, hp, scale, fac3, &first);
- }
- if (lam==0. || lam==-180.)
- SetAPen (rp, BLACK); /* reset pen to black */
- }
- }
-
- /* ============================================================= */
-
- void globe_grid_plot (double lat, double lam, double c0, double s0,
- double c1, double s1, double c2, double s2,
- long type, double hp, double scale, double fac3,
- char *first)
- /* draws globe grids */
- {
- static char latzero = FALSE;
- static char prev_in_view;
- static short h1prev, h2prev;
- static double latprev, lamprev, zpprev;
- char in_view;
- short h1, h1c; /* x-dist. (pix) from center */
- short h2, h2c; /* y-dist. (pix) from center */
- long x, y;
- double lamc; /* longitude */
- double latc; /* latitude */
- double zp, h1d, h2d, fac2;
-
- in_view = FALSE; /* get status of current point */
- zp = s1*s0 + c1*c0*c2;
- if (zp>=hp) { /* zp > hp => in view */
- in_view = TRUE;
- h1d = HRADIUS * c1 * s2;
- h2d = -VRADIUS * (s1*c0 - c1*s0*c2);
- if (type!=GLOBE_TYPE) {
- fac2 = (facp/(facp-zp))*scale;
- h1d *= fac2;
- h2d *= fac2;
- }
- h1 = h1d;
- h2 = h2d;
- }
- if (*first==TRUE) { /* get status of first point */
- *first = FALSE;
- if (in_view==TRUE) { /* if first point is in view, */
- x = h1 + CENTERX; /* move pen to first point */
- y = h2 + CENTERY; /* and plot it */
- WritePixel (rp, x, y);
- Move (rp, x, y);
- h1prev = h1;
- h2prev = h2;
- }
- prev_in_view = in_view; /* save status of first point */
- latprev = lat;
- lamprev = lam;
- zpprev = zp;
- return;
- }
- if (in_view==TRUE) { /* if current point is in view, */
- if (prev_in_view==FALSE) { /* but previous point was not */
- globe_rim_point (lat, lam, latprev, lamprev, zp, zpprev,
- c0, s0, fac3, type, latzero,
- &latc, &lamc, &h1c, &h2c);
- x = h1c + CENTERX; /* move to rim point & plot it */
- y = h2c + CENTERY;
- WritePixel (rp, x, y);
- Move (rp, x, y);
- h1prev = h1c;
- h2prev = h2c;
- }
- if (h1!=h1prev || h2!=h2prev) {
- x = h1 + CENTERX; /* draw to current point */
- y = h2 + CENTERY;
- Draw (rp, x, y);
- Move (rp, x, y);
- }
- h1prev = h1;
- h2prev = h2;
- }
- else { /* current point is out of view */
- if (prev_in_view==TRUE) { /* if previous point was in view, */
- globe_rim_point (lat, lam, latprev, lamprev, zp, zpprev,
- c0, s0, fac3, type, latzero,
- &latc, &lamc, &h1c, &h2c);
- x = h1c + CENTERX; /* draw to rim point */
- y = h2c + CENTERY;
- Draw (rp, x, y);
- Move (rp, x, y);
- }
- }
- prev_in_view = in_view; /* save status of current point */
- latprev = lat;
- lamprev = lam;
- zpprev = zp;
- }
-
- /* ============================================================= */
-
- int globe_in_view (double lat0, double lam0, double lat1, double lam1,
- double latv, double lamv, double hp)
-
- /* checks if a segment is visible */
- /* in a globe view */
- /* lat0, lam0 = coords of upper */
- /* left corner of segment (deg) */
- /* lat1, lam1 = coords of lower */
- /* right corner of segment (deg) */
- /* latv, lamv = coords of viewpoint */
- /* (deg) */
- /* hp = modified view height */
- {
- int k;
- double lat[2], lam[2], latt, lamt, del1, del2, eps;
- double lat0p, lam0p, lat1p, lam1p, latvp, lamvp, lamtp;
-
- lat0p = lat0 * RAD; /* convert to radians */
- lat1p = lat1 * RAD;
- lam0p = lam0 * RAD;
- lam1p = lam1 * RAD;
- latvp = latv * RAD;
- lamvp = lamv * RAD;
- del1 = (lat0p-lat1p)/10.; /* divide into horizontal strips */
- if (del1 > 0.) {
- eps = del1/10.;
- for (latt=lat0p; latt>=lat1p-eps; latt-=del1) {
- if ((k = limit_lam (lam, latt, latvp, hp)) == OK) {
- lam[0] += lamv;
- lam[1] += lamv;
- if (lam[0] < -PI)
- lam[0] += TWOPI;
- if (lam[0] > +PI)
- lam[0] -= TWOPI;
- if (lam[1] < -PI)
- lam[1] += TWOPI;
- if (lam[1] > +PI)
- lam[1] -= TWOPI;
- if (lam[0] <= lam1 && lam[1] >= lam0)
- return (OK);
- }
- }
- }
- del2 = (lam1p-lam0p)/10.; /* divide into vertical strips */
- if (del2 > 0.) {
- eps = del2/10.;
- for (lamt=lam0p-lamvp; lamt<=lam1p-lamvp+eps; lamt+=del2) {
- if ((lamtp = lamt) < -PI)
- lamtp += TWOPI;
- if (lamtp > +PI)
- lamtp -= TWOPI;
- if ((k = limit_lat (lat, latvp, lamtp, hp)) == OK) {
- if (lat[0] >= lat1 && lat[1] <= lat0)
- return (OK);
- }
- }
- }
- if (del1 > 0. || del2 > 0.)
- return (NOT_OK);
- return (OK); /* let globe() do degenerate case */
- }
-
- /* ============================================================= */
-
- /* get rim points for globe */
-
- void globe_rim_point (double lat, double lam, double latprev,
- double lamprev, double zp, double zpprev,
- double c0, double s0, double fac3, long type,
- char latzero, double *latc, double *lamc,
- short *h1c, short *h2c)
- {
- static int itmax = 20;
- double facz, dlat, dlam, c1, h1d, h2d;
- long x, y ,color;
- int i;
- short inc1, inc2;
-
- facz = zp / (zpprev-zp); /* get rim point by linear */
- (*latc) = lat - (latprev-lat)*facz; /* interpolation */
- (*lamc) = lam - (lamprev-lam)*facz;
- dlat = fabs (lat-latprev);
- dlam = fabs (lam-lamprev);
- if ( fabs ((*latc)-latprev)> dlat || /* if rim point not between */
- fabs ((*latc)-lat) > dlat) /* current and previous */
- (*latc) = (lat+latprev)/2.; /* point, use midpoint */
- if ( fabs ((*lamc)-lamprev)> dlam ||
- fabs ((*lamc)-lam) > dlam )
- (*lamc) = (lam+lamprev)/2.;
- if (latzero==TRUE) {
- (*h1c) = HRADIUS * cos ((*latc)) * sin ((*lamc));
- (*h2c) = -VRADIUS * sin ((*latc));
- }
- else {
- c1 = cos ((*latc));
- h1d = HRADIUS * c1 * sin ((*lamc));
- h2d = -VRADIUS * (sin ((*latc))*c0 - c1*s0*cos ((*lamc)));
- if (type!=GLOBE_TYPE) {
- h1d *= fac3;
- h2d *= fac3;
- }
- (*h1c) = h1d;
- (*h2c) = h2d;
- } /* find nearest actual rim point */
- if ((*h1c)>=0) /* right half */
- inc1 = +1;
- else /* left half */
- inc1 = -1;
- if ((*h2c)>=0) /* bottom half */
- inc2 = +1;
- else /* top half */
- inc2 = -1;
- x = (*h1c) + CENTERX + 5*inc1; /* coordinates of test pixel */
- y = (*h2c) + CENTERY + 5*inc2;
- for (i=0; i<itmax; ++i) { /* look for nearest black pixel */
- if ((color = ReadPixel (rp, x, y))==BLACK)
- break;
- x += inc1;
- y += inc2;
- }
- x -= inc1;
- y -= inc2;
- for (i=0; i<itmax; ++i) { /* look back for non-black one */
- if ((color = ReadPixel (rp, x, y)) != BLACK)
- break;
- x -= inc1;
- y -= inc2;
- }
- (*h1c) = x - CENTERX;
- (*h2c) = y - CENTERY;
- }
-
- /* ============================================================= */
-
- void grid (long type, double lat0, double lam0)
- /* controls drawing of grids */
- {
- static double lat_interval = 20.;
- static double lam_interval = 30.;
- long h1;
- double lam, lat;
-
- if (type!=FLAT_TYPE && type!=MERCATOR_TYPE)
- globe_grid (type, lat0, lam0); /* draw grid for globe */
- else { /* otherwise grid for flat */
- /* or Mercator map */
- SetAPen (rp, BLACK); /* set grid color to black */
- for (lam=-180.; lam<=+180.; lam += lam_interval) {
- h1 = lam*HFACTOR + CENTERX;
- Move (rp, h1, 0);
- Draw (rp, h1, WHEIGHT-1);
- }
- for (lat=80.; lat>=-80.; lat -= lat_interval) {
- if (type==FLAT_TYPE)
- h1 = -lat*VFACTOR;
- else
- h1 = -log (tan((lat/2.+45.)*RAD)) * M_VFACTOR;
- h1 += CENTERY;
- Move (rp, 0, h1);
- Draw (rp, WWIDTH-1, h1);
- }
- SetAPen (rp, WHITE); /* draw coordinate axes in white */
- Move (rp, CENTERX, 0);
- Draw (rp, CENTERX, WHEIGHT-1);
- Move (rp, 0, CENTERY);
- Draw (rp, WWIDTH-1, CENTERY);
- }
- }
-
- /* ============================================================= */
-
- int init_helpitems (void) /* initializes help info */
-
- {
- FILE *helpfile;
- struct Gadget *gadgetpointer;
- long x, y;
- int gadgetnum;
- int ix, numrd, i;
-
- if ((helpbuffer = (char *) calloc (1, (unsigned) HELPBUFSIZE)) == NULL)
- return (NOT_OK);
- if ((helpfile = fopen (helpfilename, "rb")) == NULL) {
- free (helpbuffer);
- helpbuffer = NULL;
- return (NOT_OK);
- }
- if ((numrd = fread (helpbuffer, sizeof(char), HELPBUFSIZE, helpfile))
- <= 0) {
- fclose (helpfile);
- free (helpbuffer);
- helpbuffer = NULL;
- return (NOT_OK);
- }
- fclose (helpfile);
- ix = 1;
- gadgetlist[0].disp = 0;
- for (i=0; i<numrd-1; ++i) { /* get disp to each help entry */
- if (helpbuffer[i] == '\f') { /* replace formfeed with eol to */
- helpbuffer[i] = '\0'; /* facilitate text display */
- gadgetlist[ix].disp = i+1;
- ++ix;
- if (ix > NUMGADGETS)
- break;
- }
- } /* now link the gadgets */
- for (gadgetnum=0; gadgetnum<NUMGADGETS; ++gadgetnum) {
- x = HGADGETSTARTX + (gadgetnum&1) * (HWIDTH/2);
- y = HGADGETSTARTY + s->Font->ta_YSize + (gadgetnum/2) *
- (HGAD_HEIGHT+HGAP);
- LinkGadget (&gadgetblocks[gadgetnum],
- gadgetlist[gadgetnum].text,
- &newhelpw, (long) x, (long) y);
- gadgetblocks[gadgetnum].Gadget.GadgetID = gadgetnum;
- } /* put exit gadget at top */
- gadgetpointer = &gadgetblocks[NUMGADGETS-1].Gadget;
- gadgetpointer->TopEdge = HTOP_MARGIN;
- gadgetpointer->LeftEdge = (HWIDTH-gadgetpointer->Width) / 2;
- return (OK);
- }
-
- /* ============================================================= */
-
- void init_requesters (void) /* initializes the requesters */
-
- {
- static char title_file[] = "Select save file name:";
- unsigned char *s, *t;
-
- InitRequester (&req); /* initialize the requester */
- req.LeftEdge = TLEFT;
- req.TopEdge = TTOP;
- req.Width = TWIDTH;
- req.Height = THEIGHT;
- req.ReqGadget = &gad;
- req.ReqText = &rtext; /* assume text input */
- req.BackFill = ORANGE;
- req.Flags = 0;
- req.ReqBorder = &border_top;
- s = &user_text_input[0]; /* copy default text string */
- t = &default_text[0];
- while ((*s++ = *t++) != '\0')
- ;
- s = &user_double_input[0]; /* copy default orbital height */
- sprintf (default_double, "%.2lf", VIEW_HEIGHT);
- t = &default_double[0];
- while ((*s++ = *t++) != '\0')
- ;
-
- colorstruct.window = w; /* window id for color requester */
-
- pathname[0] = 0; /* initialize file requester */
- filereq.Title = title_file; /* window title */
- filereq.Dir = directoryname; /* space for dir name */
- filereq.File = filename; /* space for file name */
- filereq.PathName = pathname; /* space for path name */
- filereq.Window = w; /* display on map window */
- filereq.Flags = FRQCACHINGM; /* cache the filenames */
- filereq.Flags |= FRQSAVINGM; /* saving files */
- filereq.dirnamescolor = ORANGE; /* dir names */
- filereq.filenamescolor = LT_YEL; /* file names */
- filereq.devicenamescolor = BLACK; /* device names */
- filereq.detailcolor = BLUE; /* window gadgets */
- filereq.blockcolor = DK_YEL; /* title bar */
- filereq.gadgettextcolor = DK_YEL; /* text in gadgets */
- filereq.textmessagecolor = DK_YEL; /* text in title */
- filereq.stringnamecolor = DK_YEL; /* prompts */
- filereq.stringgadgetcolor= LT_BL; /* borders */
- filereq.boxbordercolor = LT_BL;
- filereq.gadgetboxcolor = LT_BL;
-
- trs.MiddleText = "OK"; /* initialize items in */
- trs.PositiveText = 0; /* help requester */
- trs.NegativeText = 0;
- trs.KeyMask = 0;
- trs.textcolor = ORANGE;
- trs.detailcolor = BLUE;
- trs.blockcolor = DK_YEL;
- trs.versionnumber = REQVERSION;
- trs.Timeout = 0;
- trs.AbortMask = 0;
- trs.rfu1 = 0;
- }
-
- /* ============================================================= */
-
- int limit_lam (double *lam, double lat, double lat0, double etap)
- /* computes limits on longitude */
- /* for constant latitude */
- {
- double alpha;
-
- alpha = (etap-sin(lat)*sin(lat0)) / (cos(lat)*cos(lat0));
- if (alpha<=-1.) { /* negative => lamda covers */
- lam[0] = -180.; /* entire hemisphere */
- lam[1] = +180.;
- return (OK);
- }
- else if (alpha>=+1.) /* positive => nothing in view */
- return (NOT_OK);
- else { /* otherwise, compute limits */
- lam[0] = -acos (alpha)/RAD;
- lam[1] = -lam[0];
- return (OK);
- }
- }
-
- /* ============================================================= */
-
- int limit_lat (double *lat, double lat0, double lam, double etap)
- /* computes limits on latitude */
- /* for constant longitude */
- {
- double radical, a, b, sum, fac1;
-
- a = sin (lat0);
- b = cos (lat0) * cos (lam);
- sum = a*a + b*b;
- if ((radical = sum - etap*etap) <= 0.) /* no real solutions */
- return (NOT_OK);
- else { /* two real solutions */
- radical = sqrt (radical); /* solve quadratic equation */
- fac1 = (a*etap + b*radical)/sum;
- lat[0] = asin (fac1)/RAD;
- fac1 = (a*etap - b*radical)/sum;
- lat[1] = asin (fac1)/RAD;
- if (lat[0]<lat[1]) { /* put in correct order */
- b = lat[0];
- lat[0] = lat[1];
- lat[1] = b;
- }
- if (a>etap) /* check North pole */
- lat[0] = 90.;
- if (a<-etap) /* check South pole */
- lat[1] = -90.;
- return (OK);
- }
- }
-
- /* ================================================================ */
-
- void loadmappic (void) /* loads initial flat map */
-
- {
- IFFP Iresult;
-
- IlbmFrame.iWindow = w;
- IlbmFrame.iScreen = s;
- IlbmFrame.iUserFlags = 0;
- got_flat_map = NOT_OK;
- if ((Iresult = LoadIFFToWindow (flatmapfile, &IlbmFrame)) == IFF_OKAY) {
- got_flat_map = OK;
- savemappic ();
- ShowTitle (s, TRUE);
- title_toggle = TRUE;
- }
- }
-
- /* ================================================================ */
-
- int printmap (struct Window *win) /* prints displayed map */
-
- {
- struct IODRPReq *ioreq;
- struct MsgPort *printerport;
- struct IntuiMessage *msg;
- static char printerportname[] = "drmapdump";
- static char printerdevice[] = "printer.device";
- static char print_canx[] = "Printing canceled. Please wait ...";
- static char print_error[] = "Printer error ... printing aborted";
- char abort;
- int returncode;
- unsigned long signal, winsig, printsig;
-
- abort = NULL;
- ModifyIDCMP (win, MOUSEBUTTONS); /* disable all but mousebuttons */
- if ((printerport = CreatePort (printerportname, 0)) != NULL) {
- if ((ioreq = (struct IODRPReq *) CreateExtIO (printerport,
- sizeof (struct IODRPReq))) != NULL) {
- if ( ! (OpenDevice (printerdevice, 0,
- (struct IORequest *) ioreq, 0))) {
- ioreq->io_Command = CMD_FLUSH;
- DoIO ((struct IORequest *) ioreq);
- if (ioreq->io_Error == PDERR_NOERR) {
- winsig = 1 << win->UserPort->mp_SigBit;
- printsig = 1 << printerport->mp_SigBit;
- ioreq->io_Command = PRD_DUMPRPORT;
- ioreq->io_RastPort = rp;
- ioreq->io_ColorMap = vp->ColorMap;
- ioreq->io_Modes = VMODE; /* vp->Modes;*/
- ioreq->io_SrcX = 0;
- ioreq->io_SrcY = 0;
- ioreq->io_SrcWidth = WWIDTH;
- ioreq->io_SrcHeight = WHEIGHT;
- ioreq->io_DestCols = 0;
- ioreq->io_DestRows = 0;
- ioreq->io_Special = SPECIAL_ASPECT|SPECIAL_FULLROWS;
-
- SendIO ((struct IORequest *) ioreq);
- while (abort == NULL) {
- signal = Wait (printsig | winsig);
- if (signal & winsig) {
- while ((msg = (struct IntuiMessage *)
- GetMsg (win->UserPort)) != NULL) {
- if (msg->Code == MENUDOWN) {
- returncode = ABORT;
- SetWindowTitles (w, 0, print_canx);
- abort |= U_ABORT;
- }
- ReplyMsg ((struct IntuiMessage *) msg);
- }
- }
- if (signal & printsig) {
- if (ioreq->io_Error != PDERR_NOERR) {
- returncode = NOT_OK;
- SetWindowTitles (w, 0, print_error);
- abort |= P_ABORT;
- }
- else
- abort |= NOABORT; /* ahem, not aborted, but ended OK */
- }
- }
- if (abort == U_ABORT) { /* WAIT A MOMENT, crashes if */
- /* printer.device is being */
- /* loaded and printing is */
- /* canceled */
- DisplayBeep (0);
- Delay (8 * TICKS_PER_SECOND);
- AbortIO ((struct IORequest *)ioreq);
- WaitIO ((struct IORequest *)ioreq);
- }
- else if (abort & NOABORT)
- returncode = OK;
- while ((struct MsgPort *) GetMsg (printerport))
- ;
- }
- CloseDevice ((struct IORequest *) ioreq);
- }
- DeleteExtIO ((struct IORequest *) ioreq);
- }
- DeletePort (printerport);
- }
- ModifyIDCMP (win, IDCMPFLAGS); /* restore normal events */
- return (returncode);
- }
-
- /* ============================================================= */
-
- int readmap (void) /* reads map files into memory */
-
- {
- FILE *fin;
- int i, num_read, num_to_read;
- struct Pt *pt;
-
- for (i=0; i<NUM_MAPS; ++i) {
- num_to_read = (map[i].numpts) * sizeof (struct Pt);
- if ((pt = (struct Pt *) AllocRemember (&rememberkey, num_to_read,
- MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
- return (NOT_OK);
- if ((fin = fopen (map[i].mapname, "rb")) == NULL)
- return (NOT_OK);
- if ((num_read = fread (pt, sizeof (char), num_to_read, fin))
- != num_to_read) {
- fclose (fin);
- return (NOT_OK);
- }
- fclose (fin);
- map[i].pt = pt;
- }
- return (OK);
- }
-
- /* ============================================================= */
-
- void savemappic (void) /* moves map from screen to */
- /* temporary bitmap */
- {
- ShowTitle (s, FALSE); /* don't save window title bar */
- BltBitMapRastPort (rp->BitMap, 0, 0, &map_rp, 0, 0, WWIDTH, WHEIGHT,
- 0xc0);
- ShowTitle (s, title_toggle);
- }
-
- /* ================================================================ */
-
- int save_to_disk (void) /* saves map to disk */
-
- {
- int result;
- IFFP iffresult;
-
- if ( (result = FileRequester (&filereq)) != TRUE) /* get file name */
- return (NOT_OK);
- ShowTitle (s, FALSE); /* turn off title in saved file */
- SetPointer (w, waiter, WAITER_SIZE/4-2, 16,
- WAITER_X_OFFSET, WAITER_Y_OFFSET);
- iffresult = SaveWindowToIFF (pathname, w); /* save map to disk */
- SetPointer (w, arrow, ARROW_SIZE/4-2, 16,
- ARROW_X_OFFSET, ARROW_Y_OFFSET);
- ShowTitle (s, title_toggle);
- if (iffresult != IFF_OKAY) /* set return code */
- return (NOT_OK);
- else
- return (OK);
- }
-
- /* ============================================================= */
-
- void shadow (void) /* makes shadowed screens */
- /* shadows all colors except */
- /* blue and black */
- {
- static char first = NOT_OK;
- static int blackcolor[DEPTH], disp;
- static int bluecolor[DEPTH];
- static unsigned int bitval[] = {1, 2, 4, 8, 16, 32, 64, 128};
- static short ytable[WHEIGHT]; /* offsets from beginning of */
- /* each screen row */
- int modb0, modb1, color[DEPTH];
- int bcolor[DEPTH];
- int j, k, k1, k2, m, bitlast;
- int test, t;
- unsigned int byte[DEPTH];
- unsigned int byteb0[DEPTH], byteb1[DEPTH];
-
- if (first==NOT_OK) { /* initialize color values once */
- first = OK;
- test = BLACK;
- blackcolor[0] = test&bitval[0];
- for (k=1; k<DEPTH; ++k)
- blackcolor[k] = (test&bitval[k]) >> k;
- test = BLUE;
- bluecolor[0] = test&bitval[0];
- for (k=1; k<DEPTH; ++k)
- bluecolor[k] = (test&bitval[k]) >> k;
- ytable[0] = 0; /* initialize screen offsets */
- for (k=1; k<WHEIGHT; ++k)
- ytable[k] = ytable[k-1] + ROWOFFSET;
- disp = SHADOW_DISP * ROWOFFSET; /* offset to shadowed row */
- }
- for (k=ytable[0]; k<ytable[WHEIGHT-SHADOW_DISP-1]; k+=ROWOFFSET) {
- /* do each row */
- k2 = k + disp; /* displacement to shadowed row */
- for (j=0; j<ROWOFFSET; ++j) { /* do each byte in row */
- for (k1=0; k1<DEPTH; ++k1) {
- byte[k1] = bp[k1][k+j]; /* current row */
- byteb0[k1] = bp[k1][k2+j]; /* shadowed row */
- byteb1[k1] = bp[k1][k2+j+1]; /* shadowed row, adjacent byte */
- } /* if last byte in row, don't */
- /* need adjacent bytes */
- ((j<ROWOFFSET-1) ? (bitlast=0) : (bitlast=SHADOW_DISP));
- modb0 = NOT_OK;
- modb1 = NOT_OK;
- for (m=7; m>=bitlast; --m) { /* check each bit, left to right */
- for (k1=0; k1<DEPTH; ++k1) {
- t = byte[k1];
- color[k1] = BITVAL(t, m); /* current pixel color */
- }
- test = color[DEPTH-1]; /* build color value */
- for (k1=DEPTH-2; k1>=0; --k1)
- test = (test<<1) | color[k1];
- if (test != BLACK && test != BLUE) {
- if (m>SHADOW_DISP-1) { /* get color of pixel */
- for (k1=0; k1<DEPTH; ++k1) { /* in shadowed row */
- t = byteb0[k1];
- bcolor[k1] = BITVAL(t, m-SHADOW_DISP);
- }
- }
- else { /* use adjacent byte */
- for (k1=0; k1<DEPTH; ++k1) {
- t = byteb1[k1];
- bcolor[k1] = BITVAL(t, m+8-SHADOW_DISP);
- }
- }
- test = OK;
- for (k1=0; k1<DEPTH; ++k1) { /* check if it is blue */
- if (bcolor[k1] != bluecolor[k1]) {
- test = NOT_OK;
- break;
- }
- }
- if (test == OK) { /* if blue, set color to black */
- if (m>SHADOW_DISP-1) {
- for (k1=0; k1<DEPTH; ++k1) {
- t = byteb0[k1];
- BITSTORE(t, m-SHADOW_DISP, blackcolor[k1]);
- byteb0[k1] = t;
- }
- modb0 = OK;
- }
- else { /* use adjacent byte */
- for (k1=0; k1<DEPTH; ++k1) {
- t = byteb1[k1];
- BITSTORE(t, m+8-SHADOW_DISP, blackcolor[k1]);
- byteb1[k1] = t;
- }
- modb1 = OK;
- }
- }
- }
- } /* end bit test */
- if (modb0==OK) { /* restore only modified bytes */
- for (k1=0; k1<DEPTH; ++k1)
- bp[k1][k2+j] = byteb0[k1];
- }
- if (modb1==OK) {
- for (k1=0; k1<DEPTH; ++k1)
- bp[k1][k2+j+1] = byteb1[k1];
- }
- } /* end of row */
- } /* last row */
- }
-
- /* ============================================================= */
-
- void showmappic (void) /* moves map from temporary */
- /* bitmap to screen */
- {
- if (got_flat_map != OK) /* check if have already */
- fullmap (FLAT_TYPE); /* saved a flat map */
- else
- BltBitMapRastPort (&map_bitmap, 0, 0, rp, 0, 0, WWIDTH, WHEIGHT, 0xc0);
- }
-
- /* ============================================================= */
-
- void stars (void) /* draws stars into black background */
-
- {
- static char init = FALSE;
- static int nmax = 150; /* max number of stars */
- time_t systime;
- unsigned int t;
- int nstars;
- long x, y, color;
-
- if (init == FALSE) { /* initialize seed value */
- init = TRUE; /* with system time */
- t = (int) time (&systime);
- srand (t);
- }
- SetAPen (rp, WHITE);
- nstars = 0;
- while (nstars < nmax) {
- t = rand();
- x = t % WWIDTH + 1;
- t = rand();
- y = t % WHEIGHT + 1;
- if ((color = ReadPixel (rp, x, y)) == BLACK) {
- WritePixel (rp, x, y);
- ++nstars;
- }
- }
- }
-